package net.csdn.business.common.service;

import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.Supplier;

/**
 * @author likun
 * @date 2022/6/18 16:09
 */
@Slf4j
public class CommonAsyncService {
    private final long threadCommonTimeoutLimit;
    private final ThreadPoolTaskExecutor taskExecutor;

    public CommonAsyncService(long threadCommonTimeoutLimit, ThreadPoolTaskExecutor taskExecutor) {
        this.threadCommonTimeoutLimit = threadCommonTimeoutLimit;
        this.taskExecutor = taskExecutor;
    }

    public <P> P getAsyncResult(CompletableFuture<P> future, long timeout) {
        try {
            return future.get(timeout, TimeUnit.MILLISECONDS);
        } catch (InterruptedException | ExecutionException | TimeoutException e) {
            log.error("getAsyncResult get async result error. ex:{}", JSON.toJSONString(e));
        }
        return null;
    }

    public <P> P getAsyncResult(CompletableFuture<P> future, long timeout, P defaultValue) {
        try {
            return future.get(timeout, TimeUnit.MILLISECONDS);
        } catch (InterruptedException | ExecutionException | TimeoutException e) {
            log.error("getAsyncResult get async result error. ex:{}", JSON.toJSONString(e));
        }
        return defaultValue;
    }

    public <P> P getAsyncResult(CompletableFuture<P> future, P defaultValue) {
        return getAsyncResult(future, threadCommonTimeoutLimit, defaultValue);
    }

    public <R> CompletableFuture<R> requestAsync(Supplier<R> supplier) {
        return CompletableFuture.supplyAsync(supplier, taskExecutor);
    }

    public void asyncTask(Runnable runnable) {
        taskExecutor.execute(runnable);
    }
}